package cn.kn.triage.common.config.shiro;


import cn.kn.triage.common.config.jwt.JWTToken;
import cn.kn.triage.common.exception.CustomException;
import cn.kn.triage.common.model.RCode;
import cn.kn.triage.common.utils.JWTUtils;
import cn.kn.triage.sys.dao.PermissionDao;
import cn.kn.triage.sys.mapper.UserMapper;
import cn.kn.triage.sys.model.User;
import cn.kn.triage.sys.model.UserExample;
import cn.kn.triage.sys.vo.ActiveUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserRealm extends AuthorizingRealm {


    private final UserMapper userMapper;
    public final PermissionDao permissionDao;

    public UserRealm(UserMapper userMapper, PermissionDao permissionDao) {
        this.userMapper = userMapper;
        this.permissionDao = permissionDao;
    }

    /**
     * 大坑！，必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }

    /**
     * 只有当需要检测用户权限的时候才会调用此方法，例如checkRole,checkPermission之类的
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        List<String> permissions =activeUser.getPerms();
            //授权权限
            if (!CollectionUtils.isEmpty(permissions)) {
                authorizationInfo.addStringPermissions(permissions);
            }
        return authorizationInfo;
    }

    /**
     * 默认使用此方法进行用户名正确与否验证，错误抛出异常即可。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        String token = (String) auth.getCredentials();
        // 解密获得username，用于和数据库进行对比
        String username = JWTUtils.getUsername(token);

        if (username == null) {
            throw new CustomException(RCode.NO_USER);
        }

        UserExample userExample = new  UserExample();
        userExample.createCriteria().andLnameEqualTo(username);
        List<User> users = userMapper.selectByExample(userExample);
        if (CollectionUtils.isEmpty(users)){
            throw new CustomException(RCode.NO_USER);
        }


        if(JWTUtils.isExpire(token)){
            throw new CustomException(RCode.TOKEN_EXPIRE);
        }

        User user =users.get(0);

        if (! JWTUtils.verify(token, username, user.getPassword())) {
            throw new CustomException(RCode.NO_USER);
        }


        List<String> perms= permissionDao.getPerms(user.getId());
        List<String> temp = null;

        if(!CollectionUtils.isEmpty(perms)){
        //   temp = new ArrayList<>();
           /* List<String> finalTemp = temp;
            perms.stream().filter(p->!StringUtils.isEmpty(p))
                    .filter(p->p.contains(","))
                    .collect(Collectors.toList())
                    .forEach(p->
                            finalTemp.addAll(Arrays.asList(p.split(",")))*//*逗号分割*//*
                    );
           perms.stream().filter(p->!StringUtils.isEmpty(p))
                    .filter(p->!p.contains(","))
                    .collect(Collectors.toList());*/

         /*   temp = perms.stream().filter(p->!StringUtils.isEmpty(p))
                    .map(p->p.split(","))
                    .flatMap(Arrays::stream).collect(Collectors.toList());*/

           /* String[] split = String.join(",", perms.stream()
                    .filter(p -> !StringUtils.isEmpty(p))
                    .collect(Collectors.toList()))
                    .split(","); */
            String[] split = perms.stream()
                    .filter(p -> !StringUtils.isEmpty(p))
                    .collect(Collectors.joining(","))
                    .split(",");
            temp= Arrays.asList(split);
        }
        //过滤出url,和用户的权限
        ActiveUser activeUser = new ActiveUser();
        activeUser.setUser(user);
        activeUser.setPerms(temp);
        return new SimpleAuthenticationInfo(activeUser, token, getName());
    }
}
